package cn.ichensw.otherworldlystationbackend.service.impl;

import cn.ichensw.otherworldlystationbackend.common.DeleteRequest;
import cn.ichensw.otherworldlystationbackend.common.ErrorCode;
import cn.ichensw.otherworldlystationbackend.exception.BusinessException;
import cn.ichensw.otherworldlystationbackend.mapper.FilmTelevisionMapper;
import cn.ichensw.otherworldlystationbackend.model.dto.filmtelevision.FilmTelevisionAddRequest;
import cn.ichensw.otherworldlystationbackend.model.dto.filmtelevision.FilmTelevisionQueryRequest;
import cn.ichensw.otherworldlystationbackend.model.dto.filmtelevision.FilmTelevisionUpdateRequest;
import cn.ichensw.otherworldlystationbackend.model.entity.FilmTelevision;
import cn.ichensw.otherworldlystationbackend.model.entity.FilmTelevisionUser;
import cn.ichensw.otherworldlystationbackend.model.entity.User;
import cn.ichensw.otherworldlystationbackend.model.vo.bangumi.ImageVO;
import cn.ichensw.otherworldlystationbackend.model.vo.filmtelevision.FilmTelevisionVO;
import cn.ichensw.otherworldlystationbackend.service.FilmTelevisionService;
import cn.ichensw.otherworldlystationbackend.service.FilmTelevisionUserService;
import cn.ichensw.otherworldlystationbackend.service.UserService;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author csw
 */
@Service
@Slf4j
public class FilmTelevisionServiceImpl extends ServiceImpl<FilmTelevisionMapper, FilmTelevision>
        implements FilmTelevisionService {

    @Resource
    private UserService userService;
    @Resource
    private FilmTelevisionUserService filmTelevisionUserService;
    @Resource
    private FilmTelevisionMapper filmTelevisionMapper;

    @Override
    public List<FilmTelevisionVO> listFilmTelevision(FilmTelevisionQueryRequest filmTelevisionQueryRequest, HttpServletRequest request) {
        List<FilmTelevisionVO> tvList = Lists.newArrayList();
        Integer watchStatus = filmTelevisionQueryRequest.getWatchStatus();
        String searchKeys = filmTelevisionQueryRequest.getSearchKeys();
        String type = filmTelevisionQueryRequest.getType();

        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未登录");
        }
        Long userId = loginUser.getId();

        List<FilmTelevision> filmTelevisionList = filmTelevisionMapper.findPageListByParams(watchStatus, searchKeys, userId, type);
        // 优化查询
        List<FilmTelevisionUser> filmTelevisionUserList = filmTelevisionUserService.lambdaQuery()
                .eq(FilmTelevisionUser::getUserId, userId)
                .list();
        for (FilmTelevision filmTelevision : filmTelevisionList) {
            Long filmTelevisionId = filmTelevision.getId();
            List<FilmTelevisionUser> collect = filmTelevisionUserList.stream().filter(item -> item.getFilmId().equals(filmTelevisionId)).collect(Collectors.toList());
            FilmTelevisionUser filmTelevisionUser = collect.get(0);

            FilmTelevisionVO filmTelevisionVO = new FilmTelevisionVO();
            BeanUtils.copyProperties(filmTelevision, filmTelevisionVO);
            filmTelevisionVO.setImages(JSON.parseObject(filmTelevision.getImages(), ImageVO.class));
            filmTelevisionVO.setTags(JSON.parseArray(filmTelevision.getTags(), String.class));
            filmTelevisionVO.setWatchStatus(filmTelevisionUser.getWatchStatus());
            filmTelevisionVO.setWatchProgress(filmTelevisionUser.getWatchProgress());
            tvList.add(filmTelevisionVO);
        }
        return tvList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateFilmTelevision(FilmTelevisionUpdateRequest updateRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未登录");
        }
        if (ObjectUtils.isEmpty(updateRequest)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数不能为空");
        }
        // 修改放映日期
        if (updateRequest.getAirWeekDate() != null) {
            FilmTelevision filmTelevision = new FilmTelevision();
            BeanUtils.copyProperties(updateRequest, filmTelevision);
            boolean b = this.updateById(filmTelevision);
            if (!b) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新影视信息失败");
            }
        }
        return filmTelevisionUserService.lambdaUpdate()
                .eq(FilmTelevisionUser::getUserId, loginUser.getId())
                .eq(FilmTelevisionUser::getFilmId, updateRequest.getId())
                .set(updateRequest.getWatchProgress() > 0, FilmTelevisionUser::getWatchProgress, updateRequest.getWatchProgress())
                .set(updateRequest.getWatchStatus() > 0, FilmTelevisionUser::getWatchStatus, updateRequest.getWatchStatus())
                .update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addFilmTelevision(FilmTelevisionAddRequest filmTelevisionAddRequest, HttpServletRequest request) {
        Long filmId = filmTelevisionAddRequest.getId();
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未登录");
        }
        Long userId = loginUser.getId();

        // 查询是否存在
        FilmTelevision filmTelevision = this.getById(filmId);
        if (filmTelevision == null) {
            // 1. 影片新增不存在，新增影片信息
            filmTelevision = new FilmTelevision();
            BeanUtils.copyProperties(filmTelevisionAddRequest, filmTelevision);
            // 新增影视信息
            boolean save = this.save(filmTelevision);
            if (!save) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加影视信息失败");
            }
        }
        // 2. 不管存不存在，都添加关联表信息
        FilmTelevisionUser queryFilmTelevisionUser = filmTelevisionUserService.lambdaQuery()
                .eq(FilmTelevisionUser::getFilmId, filmId)
                .eq(FilmTelevisionUser::getUserId, userId)
                .one();
        if (!ObjectUtils.isEmpty(queryFilmTelevisionUser)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户已收藏该影片");
        }

        FilmTelevisionUser filmTelevisionUser = new FilmTelevisionUser();
        filmTelevisionUser.setFilmId(filmId);
        filmTelevisionUser.setUserId(userId);
        filmTelevisionUser.setWatchStatus(filmTelevisionAddRequest.getWatchStatus());
        filmTelevisionUserService.save(filmTelevisionUser);
        return filmTelevision.getId();
    }

    @Override
    public Boolean deleteFilmTelevision(DeleteRequest deleteRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long filmId = deleteRequest.getId();
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未登录");
        }
        Long userId = loginUser.getId();
        FilmTelevisionUser televisionUser = filmTelevisionUserService.lambdaQuery()
                .eq(FilmTelevisionUser::getFilmId, filmId)
                .eq(FilmTelevisionUser::getUserId, userId)
                .one();
        if (televisionUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未收藏该影片");
        }
        return filmTelevisionUserService.removeById(televisionUser.getId());
    }

    @Override
    public FilmTelevisionVO getFilmTelevisionById(Long id, HttpServletRequest request) {
        FilmTelevision filmTelevision = this.getById(id);
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未登录");
        }

        FilmTelevisionVO vo = new FilmTelevisionVO();
        if (filmTelevision != null) {
            BeanUtils.copyProperties(filmTelevision, vo);
            vo.setImages(JSON.parseObject(filmTelevision.getImages(), ImageVO.class));
            vo.setTags(JSON.parseArray(filmTelevision.getTags(), String.class));
            FilmTelevisionUser televisionUser = filmTelevisionUserService.lambdaQuery()
                    .eq(FilmTelevisionUser::getFilmId, id)
                    .eq(FilmTelevisionUser::getUserId, loginUser.getId())
                    .one();
            if (televisionUser != null) {
                vo.setWatchStatus(televisionUser.getWatchStatus());
                vo.setWatchProgress(televisionUser.getWatchProgress());
            }
        }
        return vo;
    }


}
